package com.seng.resourcetycoon.util;

import com.seng.resourcetycoon.HelloApplication;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;

import java.io.IOException;

/**
 * A utility class responsible for managing scene transitions in a JavaFX application.
 * This class implements the Singleton design pattern to ensure a single instance
 * of the {@link Stage} and provides methods for switching between different scenes,
 * represented by their corresponding FXML files.
 */
import java.util.Stack;

import static javafx.stage.WindowEvent.WINDOW_CLOSE_REQUEST;

public class SceneUtil {

    private Stage stage;
    private Stage tempStage;
    private final Stack<Scene> sceneHistory = new Stack<>(); // 添加这个来存储场景历史

    private static SceneUtil instance;

    private SceneUtil() {
    }

    public static SceneUtil getInstance() {
        if (instance == null) {
            instance = new SceneUtil();
        }
        return instance;
    }

    public void setStage(Stage stage) {
        this.stage = stage;
    }

    /**
     * Internal method used for transitioning to a specified scene and saving it in history.
     */
    private void switchToSceneAndSave(String fxmlFilePath, String title, int w, int h) {
        Scene newScene = loadSceneFromFxml(fxmlFilePath, title, w, h);
        sceneHistory.push(newScene); // 保存新的场景到历史栈中
        stage.setScene(newScene);
        stage.show();
    }

    private Scene loadSceneFromFxml(String fxmlFilePath, String title, int w, int h) {
        FXMLLoader fxmlLoader = new FXMLLoader(HelloApplication.class.getResource(fxmlFilePath));
        Parent root = null;
        try {
            root = fxmlLoader.load();
        } catch (IOException e) {
            e.printStackTrace();
        }
        Scene scene = new Scene(root, w, h);
        stage.setTitle(title);
        return scene;
    }

    public void switchToWelcome() {
        switchToSceneAndSave("hello-view.fxml", "Welcome", 700, 500);
    }

    public void switchToGameSetup() {
        switchToSceneAndSave("game-setup.fxml", "Game setup", 700, 500);
    }

    public void switchToMarket(ResultCallback callback) {
        switchToSceneForResult("market-view.fxml", "market", 700, 630,callback);
    }

    public void switchToStore(ResultCallback callback) {
        switchToSceneForResult("store-view.fxml", "store", 700, 630,callback);
    }

    public void closeTmpStage(){
        if(tempStage != null){
            tempStage.fireEvent(new WindowEvent(stage.getOwner(),WINDOW_CLOSE_REQUEST));
        }
    }

    /**
     * Navigate back to the previous scene if available.
     */
    public void goBack() {
        if (!sceneHistory.empty()) {
            Scene previousScene = sceneHistory.pop(); // 弹出上一个场景
            stage.setScene(previousScene); // 设置为当前场景并显示
        } else {
            System.out.println("No more scenes to go back to."); // 如果没有更多场景可回退，可以处理这个情况
        }
    }

    public void switchToGamePlay() {
        switchToSceneAndSave("game-play.fxml", "play game", 900, 700);
    }

    public void switchToScene(String sceneName, ResultCallback callback) {
        switch (sceneName){
            case "Store":
                switchToStore(callback);
                break;
            case "Market":
                switchToMarket(callback);
                break;
        }

    }

    // 新增回调接口用于处理页面间的数据传递
    public interface ResultCallback<T> {
        void onResult(T result);
    }

    // 跳转并等待结果的场景切换
    public <T> void switchToSceneForResult(String fxmlFilePath, String title, int w, int h, ResultCallback<T> callback) {
        tempStage = new Stage();
        tempStage.setOnCloseRequest(event -> {
            event.consume(); // 阻止默认关闭行为
            // 这里假设你的Controller有适当的关闭逻辑，并能调用finishWithResult
            // 你需要在目标页面的控制器中实现这个逻辑
            finishWithResult(callback, tempStage, null); // 传回null或默认值，具体由你决定
            tempStage.close(); // 关闭临时舞台
        });

        switchToSceneAndSaveForTempStage(fxmlFilePath, title, w, h, tempStage);
        tempStage.show();
    }

    // 用于内部调用，设置目标场景并配置回调
    private <T> void switchToSceneAndSaveForTempStage(String fxmlFilePath, String title, int w, int h, Stage tempStage) {
        Scene newScene = loadSceneFromFxml(fxmlFilePath, title, w, h);
        tempStage.setScene(newScene);
        tempStage.setTitle(title);
    }

    // 目标页面控制器中应调用此方法来传递结果并关闭窗口
    public <T> void finishWithResult(ResultCallback<T> callback,Stage stage, T result) {
        callback.onResult(result); // 触发回调
        closeCurrent();
        stage.close(); // 关闭舞台
    }

    // 示例：关闭当前页面并打开新页面
    public void closeCurrentAndSwitchTo() {
        if (!sceneHistory.isEmpty()) {
            sceneHistory.pop(); // 移除当前场景（栈顶）
        }
        Scene scene = sceneHistory.peek();
        stage.setScene(scene);
        stage.show();
    }

    public void closeCurrent() {
        if (!sceneHistory.isEmpty()) {
            sceneHistory.pop(); // 移除当前场景（栈顶）
        }
    }
}
